package com.huangfu.learning.javabase.java.pattern.action.chainOfResponsibility;

/**
 * Created with IntelliJ IDEA.
 * Author: huangfu.daohui
 * Date: 2018/8/11
 * Time: 10:51
 * Version: 1.0
 * Description:责任链模式：为请求创建了一个接收者对象的链。这种模式给予请求的类型，对请求的发送者和接收者进行解耦。Filter
 * 参考：https://blog.csdn.net/liuwenzhe2008/article/details/70199520
 * https://blog.csdn.net/chenliguan/article/details/71437645
 * <p>
 * 主要解决：职责链上的处理者负责处理请求，客户只需要将请求发送到职责链上即可，无须关心请求的处理细节和请求的传递，所以职责链将请求的发送者和请求的处理者解耦了。
 * <p>
 * 何时使用：在处理消息的时候以过滤很多道。
 * <p>
 * 如何解决：拦截的类都实现统一接口。
 * <p>
 * 关键代码：Handler 里面聚合它自己，在 HanleRequest 里判断是否合适，如果没达到条件则向下传递，向谁传递之前 set 进去。
 * <p>
 * 优点： 1、降低耦合度。它将请求的发送者和接收者解耦。
 * 2、简化了对象。使得对象不需要知道链的结构。
 * 3、增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序，允许动态地新增或者删除责任。
 * 4、增加新的请求处理类很方便。
 * <p>
 * 缺点： 1、不能保证请求一定被接收。
 * 2、系统性能将受到一定影响，而且在进行代码调试时不太方便，可能会造成循环调用。
 * 3、可能不容易观察运行时的特征，有碍于除错。
 * <p>
 * 使用场景（javaweb多用）： 1、有多个对象可以处理同一个请求，具体哪个对象处理该请求由运行时刻自动确定。
 * 2、在不明确指定接收者的情况下，向多个对象中的一个提交一个请求。
 * 3、可动态指定一组对象处理请求。
 **/
public class ChainOfResponsibility {

    public static void main(String[] args) {

        // 构造各个领导对象
        GroupLeader groupLeader = new GroupLeader();
        Director director = new Director();
        Manager manager = new Manager();
        Boss boss = new Boss();

        // 设置上级领导处理者对象
        groupLeader.nextHandler = director;
        director.nextHandler = manager;
        manager.nextHandler = boss;

        //发起报账申请
        groupLeader.handleRequest(8000);

    }
}

/**
 * 抽象领导类
 */
abstract class Leader {

    protected Leader nextHandler;// 上级领导处理者

    /**
     * 获取处理者
     *
     * @return 处理者
     */
    abstract String getLeader();

    /**
     * 处理报账行为
     *
     * @param money 具体金额
     */
    abstract void handle(int money);

    /**
     * 自身能批复的额度权限
     *
     * @return 额度
     */
    abstract int limit();

    /**
     * 处理报账请求,如果报账不足，提交下一个领导
     *
     * @param money 能批复的报账额度
     */
    final void handleRequest(int money) {
        System.out.println(getLeader());
        if (money < limit()) {
            handle(money);
        } else {
            System.out.println("报账额度不足，提交领导");
            if (nextHandler != null) {
                nextHandler.handleRequest(money);
            }
        }
    }
}

/**
 * 组长
 */
class GroupLeader extends Leader {

    @Override
    String getLeader() {
        return "当前是组长";
    }

    @Override
    void handle(int money) {
        System.out.println("组长批复报销" + money + "元");
    }

    @Override
    int limit() {
        return 1000;
    }
}

/**
 * 主管
 */
class Director extends Leader {

    @Override
    String getLeader() {
        return "当前是主管";
    }

    @Override
    void handle(int money) {
        System.out.println("主管审批报销" + money + "元");
    }

    @Override
    int limit() {
        return 5000;
    }
}

class Manager extends Leader {

    @Override
    String getLeader() {
        return "当前领导是经理";
    }

    @Override
    void handle(int money) {
        System.out.println("经理审批报销" + money + "元");
    }

    @Override
    int limit() {
        return 10000;
    }
}

/**
 * 老板
 */
class Boss extends Leader {
    @Override
    String getLeader() {
        return "当前领导是BOSS";
    }

    @Override
    void handle(int money) {
        System.out.println("BOSS审批金额" + money + "元");
    }

    @Override
    int limit() {
        return Integer.MAX_VALUE;
    }
}